using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using OracleInternal.Common;

namespace Oracle.ManagedDataAccess.Types
{
	[Serializable]
	[XmlSchemaProvider("GetXsdType")]
	public struct OracleBoolean : IComparable, INullable, IXmlSerializable
	{
		public static readonly OracleBoolean False;

		public static readonly OracleBoolean True;

		public static readonly OracleBoolean Null;

		public static readonly OracleBoolean One;

		public static readonly OracleBoolean Zero;

		private bool m_valueBool;

		private byte m_valueByte;

		private bool m_bNotNull;

		public bool IsTrue
		{
			get
			{
				if (m_bNotNull)
				{
					if (m_valueBool)
					{
						return true;
					}
					return false;
				}
				return false;
			}
		}

		public bool IsFalse
		{
			get
			{
				if (m_bNotNull)
				{
					if (!m_valueBool)
					{
						return true;
					}
					return false;
				}
				return false;
			}
		}

		public byte ByteValue
		{
			get
			{
				if (m_bNotNull)
				{
					return m_valueByte;
				}
				throw new OracleNullValueException();
			}
		}

		public bool IsNull => !m_bNotNull;

		public bool Value
		{
			get
			{
				if (m_bNotNull)
				{
					return m_valueBool;
				}
				throw new OracleNullValueException();
			}
		}

		static OracleBoolean()
		{
			False = new OracleBoolean(value: false);
			True = new OracleBoolean(value: true);
			One = new OracleBoolean(1);
			Zero = new OracleBoolean(0);
		}

		public OracleBoolean(bool value)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleBoolean, OracleTraceFuncName.ctor);
			}
			m_bNotNull = true;
			m_valueBool = value;
			if (m_valueBool)
			{
				m_valueByte = 1;
			}
			else
			{
				m_valueByte = 0;
			}
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleBoolean, OracleTraceFuncName.ctor);
			}
		}

		public OracleBoolean(int value)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleBoolean, OracleTraceFuncName.ctor);
			}
			m_bNotNull = true;
			if (value == 0)
			{
				m_valueByte = 0;
				m_valueBool = false;
			}
			else
			{
				m_valueByte = 1;
				m_valueBool = true;
			}
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleBoolean, OracleTraceFuncName.ctor);
			}
		}

		public static XmlQualifiedName GetXsdType(XmlSchemaSet schemaSet)
		{
			return new XmlQualifiedName("boolean", "http://www.w3.org/2001/XMLSchema");
		}

		XmlSchema IXmlSerializable.GetSchema()
		{
			return null;
		}

		void IXmlSerializable.ReadXml(XmlReader reader)
		{
			string attribute = reader.GetAttribute("null", "http://www.w3.org/2001/XMLSchema-instance");
			if (attribute == null || !XmlConvert.ToBoolean(attribute))
			{
				m_valueBool = Convert.ToBoolean(reader.ReadElementString());
				m_bNotNull = true;
			}
			else
			{
				m_bNotNull = false;
			}
		}

		void IXmlSerializable.WriteXml(XmlWriter writer)
		{
			if (m_bNotNull)
			{
				writer.WriteString(Convert.ToString(m_valueBool));
			}
			else
			{
				writer.WriteAttributeString("xsi", "null", "http://www.w3.org/2001/XMLSchema-instance", "true");
			}
		}

		public int CompareTo(object obj)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleBoolean, OracleTraceFuncName.CompareTo);
			}
			if (obj.GetType() != typeof(OracleBoolean))
			{
				throw new ArgumentException();
			}
			OracleBoolean value = (OracleBoolean)obj;
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleBoolean, OracleTraceFuncName.CompareTo);
			}
			return CompareTo(value);
		}

		public int CompareTo(OracleBoolean value)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleBoolean, OracleTraceFuncName.CompareTo);
			}
			try
			{
				if (!m_bNotNull && !value.m_bNotNull)
				{
					return 0;
				}
				if (!m_bNotNull && value.m_bNotNull)
				{
					return -1;
				}
				if (m_bNotNull && !value.m_bNotNull)
				{
					return 1;
				}
				if (m_valueByte < value.m_valueByte)
				{
					return -1;
				}
				if (m_valueByte > value.m_valueByte)
				{
					return 1;
				}
				return 0;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleBoolean, OracleTraceFuncName.CompareTo);
				}
			}
		}

		public override bool Equals(object obj)
		{
			if (ProviderConfig.m_bTraceLevelPublic)
			{
				Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Entry, OracleTraceClassName.OracleBoolean, OracleTraceFuncName.Equals);
			}
			try
			{
				if (obj == null)
				{
					return false;
				}
				if (obj.GetType() != typeof(OracleBoolean))
				{
					return false;
				}
				OracleBoolean value = (OracleBoolean)obj;
				if (!m_bNotNull && !value.m_bNotNull)
				{
					return true;
				}
				if (!m_bNotNull || !value.m_bNotNull)
				{
					return false;
				}
				return (this == value).m_valueBool;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPublic)
				{
					Trace.Write(OracleTraceLevel.Public, OracleTraceTag.Exit, OracleTraceClassName.OracleBoolean, OracleTraceFuncName.Equals);
				}
			}
		}

		public static OracleBoolean Equals(OracleBoolean value1, OracleBoolean value2)
		{
			return value1 == value2;
		}

		public static OracleBoolean NotEquals(OracleBoolean value1, OracleBoolean value2)
		{
			return value1 != value2;
		}

		public static OracleBoolean And(OracleBoolean value1, OracleBoolean value2)
		{
			return value1 & value2;
		}

		public static OracleBoolean Or(OracleBoolean value1, OracleBoolean value2)
		{
			return value1 | value2;
		}

		public static OracleBoolean Xor(OracleBoolean value1, OracleBoolean value2)
		{
			return value1 ^ value2;
		}

		public static OracleBoolean OnesComplement(OracleBoolean value1)
		{
			return ~value1;
		}

		public static OracleBoolean GreaterThan(OracleBoolean value1, OracleBoolean value2)
		{
			return value1 > value2;
		}

		public static OracleBoolean GreaterThanOrEquals(OracleBoolean value1, OracleBoolean value2)
		{
			return value1 >= value2;
		}

		public static OracleBoolean LessThan(OracleBoolean value1, OracleBoolean value2)
		{
			return value1 < value2;
		}

		public static OracleBoolean LessThanOrEquals(OracleBoolean value1, OracleBoolean value2)
		{
			return value1 <= value2;
		}

		public static OracleBoolean Parse(string str)
		{
			if (str == null)
			{
				throw new ArgumentNullException("str");
			}
			if (str == "")
			{
				throw new IndexOutOfRangeException();
			}
			return new OracleBoolean(bool.Parse(str));
		}

		public override int GetHashCode()
		{
			if (m_bNotNull)
			{
				return m_valueBool.GetHashCode();
			}
			return 0;
		}

		public override string ToString()
		{
			if (m_bNotNull)
			{
				if (m_valueBool)
				{
					return "True";
				}
				return "False";
			}
			return "null";
		}

		public static OracleBoolean operator &(OracleBoolean value1, OracleBoolean value2)
		{
			if (value1.m_bNotNull && value2.m_bNotNull)
			{
				return new OracleBoolean(value1.m_valueByte & value2.m_valueByte);
			}
			return Null;
		}

		public static OracleBoolean operator |(OracleBoolean value1, OracleBoolean value2)
		{
			if (value1.m_bNotNull && value2.m_bNotNull)
			{
				return new OracleBoolean(value1.m_valueByte | value2.m_valueByte);
			}
			return Null;
		}

		public static OracleBoolean operator ==(OracleBoolean value1, OracleBoolean value2)
		{
			if (value1.m_bNotNull && value2.m_bNotNull)
			{
				return new OracleBoolean(value1.m_valueByte == value2.m_valueByte);
			}
			return Null;
		}

		public static OracleBoolean operator !=(OracleBoolean value1, OracleBoolean value2)
		{
			if (value1.m_bNotNull && value2.m_bNotNull)
			{
				return new OracleBoolean(value1.m_valueByte != value2.m_valueByte);
			}
			return Null;
		}

		public static OracleBoolean operator ^(OracleBoolean value1, OracleBoolean value2)
		{
			if (value1.m_bNotNull && value2.m_bNotNull)
			{
				return new OracleBoolean(value1.m_valueByte ^ value2.m_valueByte);
			}
			return Null;
		}

		public static OracleBoolean operator !(OracleBoolean value1)
		{
			if (value1.m_bNotNull)
			{
				return new OracleBoolean(!value1.m_valueBool);
			}
			return Null;
		}

		public static OracleBoolean operator ~(OracleBoolean value1)
		{
			if (value1.m_bNotNull)
			{
				return !value1;
			}
			return Null;
		}

		public static bool operator true(OracleBoolean value1)
		{
			return value1.IsTrue;
		}

		public static bool operator false(OracleBoolean value1)
		{
			return value1.IsFalse;
		}

		public static OracleBoolean operator >(OracleBoolean value1, OracleBoolean value2)
		{
			if (value1.m_bNotNull && value2.m_bNotNull)
			{
				return new OracleBoolean(value1.m_valueByte > value2.m_valueByte);
			}
			return Null;
		}

		public static OracleBoolean operator <(OracleBoolean value1, OracleBoolean value2)
		{
			if (value1.m_bNotNull && value2.m_bNotNull)
			{
				return new OracleBoolean(value1.m_valueByte < value2.m_valueByte);
			}
			return Null;
		}

		public static OracleBoolean operator >=(OracleBoolean value1, OracleBoolean value2)
		{
			if (value1.m_bNotNull && value2.m_bNotNull)
			{
				return new OracleBoolean(value1.m_valueByte >= value2.m_valueByte);
			}
			return Null;
		}

		public static OracleBoolean operator <=(OracleBoolean value1, OracleBoolean value2)
		{
			if (value1.m_bNotNull && value2.m_bNotNull)
			{
				return new OracleBoolean(value1.m_valueByte <= value2.m_valueByte);
			}
			return Null;
		}

		public static implicit operator OracleBoolean(bool value1)
		{
			return new OracleBoolean(value1);
		}

		public static explicit operator bool(OracleBoolean value1)
		{
			return value1.Value;
		}

		public static explicit operator OracleBoolean(byte value1)
		{
			if (value1 == 0)
			{
				return new OracleBoolean(value: false);
			}
			return new OracleBoolean(value: true);
		}

		public static explicit operator OracleBoolean(decimal value1)
		{
			if (value1 == 0m)
			{
				return new OracleBoolean(value: false);
			}
			return new OracleBoolean(value: true);
		}

		public static explicit operator OracleBoolean(double value1)
		{
			if (value1 == 0.0)
			{
				return new OracleBoolean(value: false);
			}
			return new OracleBoolean(value: true);
		}

		public static explicit operator OracleBoolean(short value1)
		{
			if (value1 == 0)
			{
				return new OracleBoolean(value: false);
			}
			return new OracleBoolean(value: true);
		}

		public static explicit operator OracleBoolean(int value1)
		{
			if (value1 == 0)
			{
				return new OracleBoolean(value: false);
			}
			return new OracleBoolean(value: true);
		}

		public static explicit operator OracleBoolean(long value1)
		{
			if (value1 == 0L)
			{
				return new OracleBoolean(value: false);
			}
			return new OracleBoolean(value: true);
		}

		public static explicit operator OracleBoolean(float value1)
		{
			if ((double)value1 == 0.0)
			{
				return new OracleBoolean(value: false);
			}
			return new OracleBoolean(value: true);
		}

		public static explicit operator OracleBoolean(string value1)
		{
			return Parse(value1);
		}
	}
}
